#ifndef __SPI_FLASH_H
#define __SPI_FLASH_H

#include "gd32f4xx.h"

#ifndef SHORT_TYPE_NAME
#define SHORT_TYPE_NAME
#define u8  uint8_t
#define u16 uint16_t
#define u32 uint32_t
#endif

#define W25Q64_SPI            SPI0
#define W25Q64_SPI_RCU        RCU_SPI0

#define W25Q64_SCL_GPIO_PIN   GPIO_PIN_5 /* PA5 */
#define W25Q64_SCL_GPIO_PORT  GPIOA /* GPIOA */
#define W25Q64_SCL_GPIO_RCU   RCU_GPIOA

#define W25Q64_MISO_GPIO_PIN  GPIO_PIN_6 /* PA6 */
#define W25Q64_MISO_GPIO_PORT GPIOA /* GPIOA */
#define W25Q64_MISO_GPIO_RCU  RCU_GPIOA

#define W25Q64_MOSI_GPIO_PIN  GPIO_PIN_7 /* PA7 */
#define W25Q64_MOSI_GPIO_PORT GPIOA /* GPIOA */
#define W25Q64_MOSI_GPIO_RCU  RCU_GPIOA

#define W25Q64_CS_GPIO_PIN    GPIO_PIN_4 /* PA4 */
#define W25Q64_CS_GPIO_PORT   GPIOA /* GPIOA */
#define W25Q64_CS_GPIO_RCU    RCU_GPIOA

#define SPI_FLASH_CS_LOW()    gpio_bit_reset(W25Q64_CS_GPIO_PORT, W25Q64_CS_GPIO_PIN)
#define SPI_FLASH_CS_HIGH()   gpio_bit_set(W25Q64_CS_GPIO_PORT, W25Q64_CS_GPIO_PIN)

void SPI_FLASH_Init(void);
void SPI_FLASH_SectorErase(u32 SectorAddr);
void SPI_FLASH_BulkErase(void);
void SPI_FLASH_PageWrite(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite);
void SPI_FLASH_BufferWrite(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite);
void SPI_FLASH_BufferWrite_Large(u8* pBuffer, u32 WriteAddr, u32 NumByteToWrite);
void SPI_FLASH_BufferRead(u8* pBuffer, u32 ReadAddr, u16 NumByteToRead);
void SPI_FLASH_BufferRead_Large(u8* pBuffer, u32 ReadAddr, u32 NumByteToRead);
u32 SPI_FLASH_ReadID(void);
u32 SPI_FLASH_ReadDeviceID(void);
void SPI_FLASH_StartReadSequence(u32 ReadAddr);
void SPI_Flash_PowerDown(void);
void SPI_Flash_WAKEUP(void);

u8 SPI_FLASH_ReadByte(void);
u8 SPI_FLASH_SendByte(u8 byte);
u16 SPI_FLASH_SendHalfWord(u16 HalfWord);
void SPI_FLASH_WriteEnable(void);
void SPI_FLASH_WaitForWriteEnd(void);

#endif /* __SPI_FLASH_H */
